﻿namespace Smart.Utils.Utils
{
    using ICSharpCode.SharpZipLib.Checksums;
    using ICSharpCode.SharpZipLib.Zip;
    using System;
    using System.Collections;
    using System.IO;
    using System.Runtime.CompilerServices;

    public class ZipHelper
    {
        public static  event UnzipCompleteEventHander UnzipComplete;

        public static  event UnzipFailEventHander UnzipFail;

        public static  event UnzipProcessEventHander UnzipProcess;

        public static void AddFilesFoldersToZip(string srcDir, string rootDir, string filter, ref ZipOutputStream zos)
        {
            foreach (string str in Directory.GetFiles(srcDir, filter))
            {
                zos.SetLevel(9);
                FileInfo info = new FileInfo(str);
                ZipEntry entry = new ZipEntry(srcDir.Remove(0, rootDir.Length) + @"\" + info.Name);
                FileStream stream = File.OpenRead(str);
                byte[] buffer = new byte[Convert.ToInt32(stream.Length)];
                stream.Read(buffer, 0, (int) stream.Length);
                entry.DateTime = info.LastWriteTime;
                entry.Size = stream.Length;
                stream.Close();
                zos.PutNextEntry(entry);
                zos.Write(buffer, 0, buffer.Length);
                buffer = null;
            }
            foreach (string str2 in Directory.GetDirectories(srcDir))
            {
                AddFilesFoldersToZip(str2, rootDir, filter, ref zos);
            }
        }

        public static void CompressFile(string sPath, string descZipFile)
        {
            ZipOutputStream stream = new ZipOutputStream(File.Create(descZipFile));
            FileInfo info = new FileInfo(sPath);
            ZipEntry entry = new ZipEntry(info.Name);
            FileStream stream2 = File.OpenRead(sPath);
            byte[] buffer = new byte[Convert.ToInt32(stream2.Length)];
            stream2.Read(buffer, 0, (int) stream2.Length);
            entry.DateTime = info.LastWriteTime;
            entry.Size = stream2.Length;
            stream2.Close();
            stream.PutNextEntry(entry);
            stream.Write(buffer, 0, buffer.Length);
            stream.Finish();
            stream.Close();
        }

        public static byte[] CompressFolder(string folderPath)
        {
            byte[] buffer2;
            if ((folderPath == null) || (folderPath.Length <= 0))
            {
                return null;
            }
            using (MemoryStream stream = new MemoryStream())
            {
                using (ZipOutputStream stream2 = new ZipOutputStream(stream))
                {
                    Crc32 crc = new Crc32();
                    stream2.SetLevel(9);
                    DoCompressFolder(stream, stream2, crc, folderPath, folderPath);
                    stream2.Finish();
                    byte[] buffer = new byte[stream.Length];
                    stream.Seek(0L, SeekOrigin.Begin);
                    stream.Read(buffer, 0, buffer.Length);
                    stream2.Close();
                    buffer2 = buffer;
                }
            }
            return buffer2;
        }

        public static string CompressFolder(string srcDir, string destZipFile, string filter)
        {
            DateTime now = DateTime.Now;
            ZipOutputStream zos = new ZipOutputStream(File.Create(destZipFile));
            AddFilesFoldersToZip(srcDir, srcDir, filter, ref zos);
            zos.Finish();
            zos.Flush();
            zos.Close();
            TimeSpan span = (TimeSpan) (DateTime.Now - now);
            return (span.TotalMilliseconds.ToString("F") + "ms");
        }

        public static string Decompress(string zipFile, string destDir)
        {
            ZipEntry entry;
            DateTime now = DateTime.Now;
            ZipInputStream stream = new ZipInputStream(File.OpenRead(zipFile));
            while ((entry = stream.GetNextEntry()) != null)
            {
                long num;
                bool flag;
                string fileName = Path.Combine(destDir, entry.Name);
                FileInfo info = new FileInfo(fileName);
                if (!Directory.Exists(info.DirectoryName))
                {
                    Directory.CreateDirectory(info.DirectoryName);
                }
                FileStream stream2 = File.Create(fileName);
                byte[] buffer = new byte[entry.Size];
                goto Label_009C;
            Label_0069:
                num = stream.Read(buffer, 0, buffer.Length);
                if (num <= 0L)
                {
                    goto Label_00A1;
                }
                stream2.Write(buffer, 0, (int) num);
            Label_009C:
                flag = true;
                goto Label_0069;
            Label_00A1:
                stream2.Close();
            }
            TimeSpan span = (TimeSpan) (DateTime.Now - now);
            return (span.TotalMilliseconds.ToString("F") + "ms");
        }

        public static void DecompressFolder(byte[] input, string folderPath)
        {
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }
            using (MemoryStream stream = new MemoryStream(input))
            {
                using (ZipInputStream stream2 = new ZipInputStream(stream))
                {
                    ZipEntry entry;
                    while ((entry = stream2.GetNextEntry()) != null)
                    {
                        using (MemoryStream stream3 = new MemoryStream())
                        {
                            int num;
                            string str;
                            bool flag;
                            byte[] buffer = new byte[0x1000];
                            goto Label_0072;
                        Label_0040:
                            num = stream2.Read(buffer, 0, buffer.Length);
                            if (num > 0)
                            {
                                stream3.Write(buffer, 0, num);
                            }
                            else
                            {
                                goto Label_0077;
                            }
                        Label_0072:
                            flag = true;
                            goto Label_0040;
                        Label_0077:
                            str = Path.Combine(folderPath, entry.Name);
                            if (!Directory.Exists(Path.GetDirectoryName(str)))
                            {
                                Directory.CreateDirectory(Path.GetDirectoryName(str));
                            }
                            if (File.Exists(str))
                            {
                                File.Delete(str);
                            }
                            using (BinaryReader reader = new BinaryReader(stream3))
                            {
                                using (FileStream stream4 = new FileStream(str, FileMode.CreateNew, FileAccess.Write))
                                {
                                    using (BinaryWriter writer = new BinaryWriter(stream4))
                                    {
                                        byte[] buffer2 = new byte[stream3.Length];
                                        stream3.Seek(0L, SeekOrigin.Begin);
                                        reader.Read(buffer2, 0, (int) stream3.Length);
                                        writer.Write(buffer2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private static void DoCompressFolder(MemoryStream buf, ZipOutputStream zip, Crc32 crc, string baseFolderPath, string currentFolderPath)
        {
            foreach (string str in Directory.GetFiles(currentFolderPath))
            {
                string name = str.Substring(baseFolderPath.Length).Trim(new char[] { '\\' });
                using (FileStream stream = new FileStream(str, FileMode.Open, FileAccess.Read))
                {
                    using (new BinaryReader(stream))
                    {
                        byte[] buffer = new byte[stream.Length];
                        stream.Read(buffer, 0, buffer.Length);
                        ZipEntry entry = new ZipEntry(name);
                        entry.DateTime = DateTime.Now;
                        entry.Size = buffer.Length;
                        crc.Reset();
                        crc.Update(buffer);
                        entry.Crc = crc.Value;
                        zip.PutNextEntry(entry);
                        zip.Write(buffer, 0, buffer.Length);
                    }
                }
            }
            foreach (string str3 in Directory.GetDirectories(currentFolderPath))
            {
                DoCompressFolder(buf, zip, crc, baseFolderPath, str3);
            }
        }

        private static ArrayList GenerateFileList(string Dir)
        {
            ArrayList list = new ArrayList();
            bool flag = true;
            foreach (string str in Directory.GetFiles(Dir))
            {
                list.Add(str);
                flag = false;
            }
            if (flag && (Directory.GetDirectories(Dir).Length == 0))
            {
                list.Add(Dir + "/");
            }
            foreach (string str2 in Directory.GetDirectories(Dir))
            {
                foreach (object obj2 in GenerateFileList(str2))
                {
                    list.Add(obj2);
                }
            }
            return list;
        }

        private static void RaiseUnzipCompleteEventHander()
        {
            if (UnzipComplete != null)
            {
                UnzipComplete(null);
            }
        }

        private static void RaiseUnzipFailEventHander(string Message)
        {
            if (UnzipFail != null)
            {
                UnzipFail(null, Message);
            }
        }

        private static void RaiseUnzipProcessEventHander(long position)
        {
            if (UnzipProcess != null)
            {
                UnzipProcess(null, position);
            }
        }

        public static void UncompressFile(string zipFile, string destDir)
        {
            ZipEntry entry;
            ZipInputStream stream = new ZipInputStream(File.OpenRead(zipFile));
            while ((entry = stream.GetNextEntry()) != null)
            {
                long num;
                bool flag;
                FileStream stream2 = File.Create(destDir + @"\" + entry.Name);
                byte[] buffer = new byte[entry.Size];
                goto Label_0068;
            Label_0039:
                num = stream.Read(buffer, 0, buffer.Length);
                if (num <= 0L)
                {
                    goto Label_006D;
                }
                stream2.Write(buffer, 0, (int) num);
            Label_0068:
                flag = true;
                goto Label_0039;
            Label_006D:
                stream2.Close();
            }
            Console.WriteLine("Done!!");
        }

        public static string Unzipfile(string ZipPath, string UnzipPath)
        {
            Exception exception;
            try
            {
                ZipEntry entry;
                RaiseUnzipProcessEventHander(0L);
                ZipInputStream stream = new ZipInputStream(File.OpenRead(ZipPath));
                FileStream stream2 = null;
                string fileName = "";
                long num = 0L;
                while ((entry = stream.GetNextEntry()) != null)
                {
                    string directoryName = "";
                    try
                    {
                        directoryName = Path.GetDirectoryName(entry.Name);
                        if (!Directory.Exists(UnzipPath + @"\" + directoryName))
                        {
                            Directory.CreateDirectory(UnzipPath + @"\" + directoryName);
                        }
                    }
                    catch (Exception exception1)
                    {
                        exception = exception1;
                        RaiseUnzipFailEventHander(exception.Message);
                        return "";
                    }
                    fileName = Path.GetFileName(entry.Name);
                    try
                    {
                        bool flag;
                        if (!(fileName != string.Empty))
                        {
                            goto Label_0182;
                        }
                        stream2 = File.Create(UnzipPath + @"\" + directoryName + @"\" + fileName);
                        int count = 0x5000;
                        byte[] buffer = new byte[0x5000];
                        goto Label_0159;
                    Label_010C:
                        count = stream.Read(buffer, 0, buffer.Length);
                        num += count;
                        RaiseUnzipProcessEventHander((num / entry.Size) * 100L);
                        if (count > 0)
                        {
                            stream2.Write(buffer, 0, count);
                        }
                        else
                        {
                            goto Label_015E;
                        }
                    Label_0159:
                        flag = true;
                        goto Label_010C;
                    Label_015E:
                        stream2.Close();
                    }
                    catch (Exception exception2)
                    {
                        exception = exception2;
                        RaiseUnzipFailEventHander(exception.Message);
                        return "";
                    }
                Label_0182:;
                }
                if (stream2 != null)
                {
                    stream2.Close();
                }
                stream.Close();
                RaiseUnzipCompleteEventHander();
                return fileName;
            }
            catch (Exception exception3)
            {
                exception = exception3;
                RaiseUnzipFailEventHander(exception.Message);
                return exception.Message;
            }
        }

        public static void ZipFiles(string inputFolderPath, string outputPathAndFile)
        {
            ArrayList list = GenerateFileList(inputFolderPath);
            int count = Directory.GetParent(inputFolderPath).ToString().Length + 1;
            ZipOutputStream stream2 = new ZipOutputStream(File.Create(inputFolderPath + @"\" + outputPathAndFile));
            stream2.SetLevel(9);
            foreach (string str2 in list)
            {
                ZipEntry entry = new ZipEntry(str2.Remove(0, count));
                stream2.PutNextEntry(entry);
                if (!str2.EndsWith("/"))
                {
                    FileStream stream = File.OpenRead(str2);
                    byte[] buffer = new byte[stream.Length];
                    stream.Read(buffer, 0, buffer.Length);
                    stream2.Write(buffer, 0, buffer.Length);
                }
            }
            stream2.Finish();
            stream2.Close();
        }

        public delegate void UnzipCompleteEventHander(object sender);

        public delegate void UnzipFailEventHander(object sender, string Message);

        public delegate void UnzipProcessEventHander(object sender, long position);
    }
}

